<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>方法的name属性</title>
</head>
<body>
  <script>
    // 函数的name属性，返回函数名。对象方法也是函数，因此有name属性。
    var person = {
      sayName() {
        console.log('hello')
      }
    }
    var a = person.sayName.name;
    console.log(a) // sayName
    // 上面代码中，方法的name属性返回函数名(即方法名)
  </script>
  <script>
    // 如果对象的方法使用了取值函数(getter)和存值函数(setter),则name属性不是在该方法上面，而是在该方法的属性描述对象set和get上
    // 返回值是方法名前加上get和set.
    var obj = {
      get foo() {},
      set foo(x) {}
    };
    // var a = obj.foo.name;
    // console.log(a) // Cannot read property 'name' of undefined
    var descriptor = Object.getOwnPropertyDescriptor(obj, 'foo');
    var b = descriptor.get.name;
    var c = descriptor.set.name;
    console.log(b);//"get foo"
    console.log(c);//"set foo"
    /**
     * 有俩种特殊情况：bind方法创造的函数，name属性返回bound加上原函数名；
     *Function构造函数创造的函数，name属性返回anonymous
    */
   (new Function()).name; // 'anonymous'
   var doSomething = function() {
     // code
   };
   doSomething.bind().name// bound doSomething
  </script>
  <script>
    // 如果对象的方法是一个Symbol值，那么name属性返回的是这个Symbol值的描述。
    var key1 = Symbol('description');
    var key2 = Symbol();
    var obj = {
      [key1]() {},
      [key2]() {}
    };
    obj[key1].name; // '[description]'
    obj[key2].name; // ''
    // 上面代码中，key1对应的Symbol值有描述，key2没有。
  </script>
</body>
</html>